package com.fs.luban.security.interceptor;

import java.util.Collection;

import javax.servlet.http.HttpServletRequest;

import org.springframework.security.access.AccessDecisionVoter;
import org.springframework.security.access.ConfigAttribute;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.web.FilterInvocation;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;

import com.fs.luban.security.model.LubanConfigAttribute;
import com.fs.luban.security.model.LubanGrantedAuthority;

import lombok.extern.log4j.Log4j2;

/**
 * @title 鲁班自定义AccessDecisionVoter
 * @Description 实现基于restful的资源投票器
 * @author fengshi
 */
@Log4j2
public class LubanAccessDecisionVoter implements AccessDecisionVoter<Object> {

	@Override
	public boolean supports(ConfigAttribute attribute) {
		return null != attribute.getAttribute() && attribute instanceof LubanConfigAttribute;
	}

	@Override
	public boolean supports(Class<?> clazz) {
		return true;
	}

	@Override
	public int vote(Authentication authentication, Object object, Collection<ConfigAttribute> attributes) {
		if (null == authentication) {
			return ACCESS_DENIED;
		}
		HttpServletRequest request = ((FilterInvocation) object).getHttpRequest();
		String url, method;
		AntPathRequestMatcher matcher;
		for (ConfigAttribute ca : attributes) {
			// 当该对象可以被处理
			if (this.supports(ca)) {
				log.info("自定义投票器尝试处理投票...");
				for (GrantedAuthority ga : authentication.getAuthorities()) {
					LubanGrantedAuthority lubanGA = (LubanGrantedAuthority) ga;
					url = lubanGA.getUrl();
					method = lubanGA.getMethod();
					matcher = new AntPathRequestMatcher(url, method);
					if (matcher.matches(request)) {
						log.info("资源匹配...");
						return ACCESS_GRANTED;
					}
				}
			}
		}
		return ACCESS_ABSTAIN;
	}

}
